#include "Player.h"

CPlayer::CPlayer(String sName, Vector vPos, String sTextureName, RGBAColor rgbaColor)
 : CEntity(sName, vPos, sTextureName, rgbaColor), m_iScore(0), m_iPower(0)
{
    
}

void CPlayer::collidePlayers(CPlayer* player1, CPlayer* player2)
{
    
    Vector vBetween = player2->getPos() - player1->getPos();
    Scalar fDist2 = vBetween.Length2();
    Scalar fMinDist = player1->getCollisionRadius() + player2->getCollisionRadius();
    
    Scalar fSquishAngle = 10.f DEG_TO_RAD;
    
    //Check if the entities have collided
    if (fDist2 < fMinDist*fMinDist) {
        
        Scalar fDist = sqrt(fDist2);
        
        Vector vNormal = vBetween / fDist;
        
        //Calculate the collision position
        Vector vPos = player1->getPos() + player1->getCollisionRadius() * vNormal;
        
        player1->getPos() -= 2 * vNormal * (fMinDist - fDist);
        player2->getPos() += 2 * vNormal * (fMinDist - fDist);
        
        Vector vForce = 0.01 * vNormal * (vNormal % (-player1->getPhysics().getVel() + player2->getPhysics().getVel()));
        
        //player1->applyForce(-vForce, vPos);
        //player2->applyForce(vForce, vPos);
        
        return;
        
        //dealWithCollisionResult(player1, player2, CR_BUMP, vPos, vNormal);
        
        //if (cos(player2->getAngle() - player1->getAngle()))
        
        Scalar fAngleBetween = vBetween.Angle();
        
        Scalar fP1Facing = fAngleBetween - player1->getAngle();
        Scalar fP2Facing = fAngleBetween - player2->getAngle();
        
        //If player1 has their head pointing away from player2
        if (fP1Facing < fSquishAngle && fP1Facing > -fSquishAngle) {
            //If player2 has their head pointing towards player1
            if (fP2Facing < fSquishAngle && fP2Facing > -fSquishAngle) {
                //Player2 dies
                //CGame::getInstance().informOfPlayerKill(player1, player2);
                dealWithCollisionResult(player1, player2, CR_PLAYER1_WINS, vPos, vBetween / sqrt(fDist2));
            }
            //If player 2 has their head pointing away from player1
            else if (fP2Facing > PI-fSquishAngle && fP2Facing > PI+fSquishAngle) {
                //Player's feet bounce off each other
                dealWithCollisionResult(player1, player2, CR_BOUNCE, vPos, vBetween / sqrt(fDist2));
            }
        }
        //If player1 has their head pointing towards player2
        else if (fP1Facing > PI-fSquishAngle && fP1Facing < PI+fSquishAngle) {
            //If player2 has their head pointing towards player1
            if (fP2Facing < fSquishAngle && fP2Facing > -fSquishAngle) {
                //Both players die
                dealWithCollisionResult(player1, player2, CR_BOTH_DIE, vPos, vBetween / sqrt(fDist2));
            }
            //If player 2 has their head pointing away from player1
            else if (fP2Facing > PI-fSquishAngle && fP2Facing > PI+fSquishAngle) {
                //Player1 dies
                dealWithCollisionResult(player1, player2, CR_PLAYER2_WINS, vPos, vBetween / sqrt(fDist2));
            }
        }
        //The players collided on their sides (they bumped each other)
        else {
            dealWithCollisionResult(player1, player2, CR_BUMP, vPos, vBetween / sqrt(fDist2));
        }
        
    }
    
}

void CPlayer::dealWithCollisionResult(CPlayer* player1, CPlayer* player2, CollisionResult iResult, Vector vPos, Vector vNormal)
{
    
    Scalar fBounceForce = 10.f;
    
    switch (iResult) {
        case CR_BOUNCE:
            {
                Vector vForce1 = vNormal * (vNormal % player1->getFacing()) * fBounceForce;
                Vector vForce2 = vNormal * (vNormal % player2->getFacing()) * fBounceForce;
                
                player1->applyForce(vForce1, vPos);
                player2->applyForce(vForce2, vPos);
                
                break;
            }
        case CR_PLAYER1_WINS:
            {
                player1->addToScore(1);
                player2->die();
                
                Vector vForce1 = vNormal * (vNormal % player1->getFacing()) * fBounceForce;
                player1->applyForce(vForce1, vPos);
                
                break;
            }
        case CR_PLAYER2_WINS:
            {    
                player2->addToScore(1);
                player1->die();
                
                Vector vForce2 = vNormal * (vNormal % player2->getFacing()) * fBounceForce;
                player2->applyForce(vForce2, vPos);
                
                break;
            }
        case CR_BOTH_DIE:
            {    
                player1->addToScore(-1);
                player2->addToScore(-1);
                
                player1->die();
                player2->die();
                
                break;
            }
        case CR_BUMP:
            {
                
                Vector vForce = -1.5f * 0.5f * vNormal * (vNormal % (player1->getPhysics().getVel() - player1->getPhysics().getVel()));
                player1->applyForce(vForce, vPos);
                player2->applyForce(-vForce, vPos);
                
                break;
                
            }
    }
    
}

void CPlayer::die()
{
    
    std::cout << m_sName << " died" << std::endl;
    
}
